using System;
using System.Collections.Generic;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;

namespace Microsoft.CRM.ThirdParty.Extensions
{
    public static class CrmServiceExtensions
    {
        public static DynamicEntity GetEntityByIdentity(this CrmService crmService, string entityName, string identityFieldName, Guid identity)
        {
            QueryExpression query = new QueryExpression();
            query.EntityName = entityName;
            query.ColumnSet = new AllColumns();

            query.Criteria.AddCondition(identityFieldName, ConditionOperator.Equal, identity);

            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.ReturnDynamicEntities = true;
            request.Query = query;

            RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)crmService.Execute(request);

            if (retrieved.BusinessEntityCollection.BusinessEntities.Count > 0)
                return (DynamicEntity) retrieved.BusinessEntityCollection.BusinessEntities[0];
            return default(DynamicEntity);
        }

        public static DynamicEntity GetEntityByColumn(this CrmService crmService, string entityName, string columnName, object value)
        {
            QueryExpression query = new QueryExpression();
            query.EntityName = entityName;
            query.ColumnSet = new AllColumns();

            query.Criteria.AddCondition(columnName, ConditionOperator.Equal, value);

            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.ReturnDynamicEntities = true;
            request.Query = query;

            RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)crmService.Execute(request);

            if (retrieved.BusinessEntityCollection.BusinessEntities.Count > 0)
                return (DynamicEntity)retrieved.BusinessEntityCollection.BusinessEntities[0];
            return default(DynamicEntity);
        }

        public static DynamicEntity GetEntityByCriteria(this CrmService crmService, string entityName, List<ConditionExpression> searchCriteria)
        {

            QueryExpression searchExpression = new QueryExpression();
            searchExpression.EntityName = entityName;
            searchExpression.ColumnSet = new AllColumns();

            if (searchCriteria.Count > 0)
                foreach (var conditionExpression in searchCriteria)
                    searchExpression.Criteria.AddCondition(conditionExpression);

            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.ReturnDynamicEntities = true;
            request.Query = searchExpression;

            RetrieveMultipleResponse response = (RetrieveMultipleResponse)crmService.Execute(request);

            if (response.BusinessEntityCollection.BusinessEntities.Count > 0)
                return (DynamicEntity) response.BusinessEntityCollection.BusinessEntities[0];

            return null;

        }

        public static List<DynamicEntity> SelectManyDynamicEntity(this CrmService crmService, string entityName, string searchAttributeName, string searchAttributeValue, ColumnSetBase columnSet)
        {
            List<DynamicEntity> retrievedDynamicEntities = new List<DynamicEntity>();

            QueryExpression query = new QueryExpression();
            query.EntityName = entityName;
            query.ColumnSet = columnSet;
            if (!string.IsNullOrEmpty(searchAttributeName) && !string.IsNullOrEmpty(searchAttributeValue))
                query.Criteria.AddCondition(searchAttributeName, ConditionOperator.Equal, searchAttributeValue);

            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.ReturnDynamicEntities = true;
            request.Query = query;

            RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)crmService.Execute(request);

            if (retrieved.BusinessEntityCollection.BusinessEntities.Count > 0)
            {
                foreach (BusinessEntity businessEntity in retrieved.BusinessEntityCollection.BusinessEntities)
                {
                    retrievedDynamicEntities.Add((DynamicEntity)businessEntity);
                }
            }

            return retrievedDynamicEntities;
        }

        public static List<DynamicEntity> SelectManyDynamicEntityWithSpecifiedConditions(this CrmService crmService, string entityName, List<ConditionExpression> conditionExpressions, ColumnSetBase columnSet)
        {
            List<DynamicEntity> entities = new List<DynamicEntity>();

            QueryExpression searchQuery = new QueryExpression();
            searchQuery.EntityName = entityName;
            searchQuery.ColumnSet = columnSet;

            if (conditionExpressions.Count > 0)
                foreach (var conditionExpression in conditionExpressions)
                    searchQuery.Criteria.AddCondition(conditionExpression);

            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.ReturnDynamicEntities = true;
            request.Query = searchQuery;

            RetrieveMultipleResponse retrievedItems = (RetrieveMultipleResponse)crmService.Execute(request);

            if (retrievedItems.BusinessEntityCollection.BusinessEntities.Count > 0)
                foreach (var businessEntity in retrievedItems.BusinessEntityCollection.BusinessEntities)
                    entities.Add((DynamicEntity) businessEntity);

            return entities;

        }

    }
}